﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel.Description;
using System.Net;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Office.Interop.Excel;
using CrmCustomizationsExcelAddIn.Data;
using System.Threading;
using CrmCustomizationsExcelAddIn.Helper;
using CrmServerConnection;

namespace CrmCustomizationsExcelAddIn
{
    public partial class CrmAuthenticationForm : Form
    {
        CrmConnection connection;
        private OrganizationDetailCollection orgResponse;
        private string exception;
        public delegate void refreshOrganizationListDelegate();
        private CrmCustomizationsRibbon parentribbon;
        private ConnectionsData connectionData;
        private string serverUri;
        private bool ssl;
        private bool savedConnection;
        private ConnectionConfiguration currentSavedConnection;
        private string currentOrg;

        public CrmAuthenticationForm(CrmCustomizationsRibbon parentribbon)
        {
            InitializeComponent();
            retriveOrganization.DoWork += new DoWorkEventHandler(retriveOrganizationWorker);
            retriveOrganization.RunWorkerCompleted += new RunWorkerCompletedEventHandler(retriveOrganizationRunWorkerCompleted);
            ConnectAndLoad.DoWork += new DoWorkEventHandler(ConnectAndLoad_DoWork);
            this.parentribbon = parentribbon;
        }


        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (login.Checked)
            {
                user.ReadOnly = true;
                password.ReadOnly = true;
            }
            else
            {
                user.ReadOnly = false;
                password.ReadOnly = false;
            }
        }

        private void cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }



        private void connect_Click(object sender, EventArgs e)
        {
            if (GlobalApplicationData.Instance.connectionInProgress)
            {
                DialogResult message = MessageBox.Show("Another connection in progress", "Connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                if (host.Text == string.Empty)
                {
                    DialogResult message = MessageBox.Show("Host missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (!protocol1.Checked && !protocol2.Checked)
                {
                    DialogResult message = MessageBox.Show("Protocol not selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (!login.Checked && user.Text == string.Empty)
                {
                    DialogResult message = MessageBox.Show("User missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (!login.Checked && password.Text == string.Empty)
                {
                    DialogResult message = MessageBox.Show("password missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                int portint;

                if (port.Text != string.Empty)
                {
                    if (!int.TryParse(port.Text, out portint) || portint < 0 || portint > 65535)
                    {
                        DialogResult message = MessageBox.Show("Wrong port number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    serverUri = host.Text + ":" + port.Text;
                }
                else
                {
                    serverUri = host.Text;
                }

                ssl = protocol2.Checked;

                if (login.Checked)
                {
                    connection = new CrmConnection(ssl, serverUri);
                }
                else
                {
                    connection = new CrmConnection(ssl, serverUri, user.Text, password.Text, ckb_office365.Checked);
                }

                if (organization.Items.Count <= 0)
                {
                    pcb_lodiang.Visible = true;
                    GlobalApplicationData.Instance.connectionInProgress = true;
                    retriveOrganization.RunWorkerAsync();
                }
            }
        }

        private void retriveOrganizationWorker(object sender, DoWorkEventArgs e)
        {
            try
            {
                GlobalApplicationData.Instance.connectionInProgress = true;
                orgResponse = connection.GetDiscoveryService();
            }
            catch (Exception ex)
            {
                exception = ex.Message;
                e.Cancel = true;
            }

        }

        private void retriveOrganizationRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                DialogResult message = MessageBox.Show(string.Format("Unable to Connect to {0} \n {1}", connection.ServerAddress.ToString(), exception), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (savedConnection)
                {
                    pnlMainPanel.Visible = true;
                    pnlOnlyPassword.Visible = false;
                    ptbLoadongBig.Visible = false;
                    cmbSavedConnections.SelectedIndex = 0;
                    savedConnection = false;
                }
            }
            System.Action action = () => pcb_lodiang.Visible = false;
            try
            {
                pcb_lodiang.Invoke(action);
                organization.Invoke(new refreshOrganizationListDelegate(refreshOrganizationList));
                if (savedConnection && currentSavedConnection != null)
                {
                    connection.OrganizationName = currentSavedConnection.organization;
                    ((ActionPanelEntityList)Globals.CrmAddIn.TaskPane.Control).showLoading(true);
                    ConnectAndLoad.RunWorkerAsync();
                    this.Close();
                }
            }
            catch (Exception)
            {
            }
            GlobalApplicationData.Instance.connectionInProgress = false;
        }

        private void refreshOrganizationList()
        {
            if (orgResponse != null)
            {
                foreach (var item in orgResponse)
                {
                    organization.Items.Add(item.FriendlyName);
                }
                if (orgResponse.Count > 0)
                {
                    organization.SelectedIndex = 0;
                }
            }
        }


        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (protocol1.Checked)
            {
                protocol2.Checked = false;
            }
            else
            {
                protocol2.Checked = true;
            }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (protocol2.Checked)
            {
                protocol1.Checked = false;
            }
            else
            {
                protocol1.Checked = true;
            }
        }


        private void ok_Click(object sender, EventArgs e)
        {
            if (GlobalApplicationData.Instance.connectionInProgress)
            {
                DialogResult message = MessageBox.Show("Another connection in progress", "Connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                string org = organization.SelectedItem.ToString();
                if (ckb_SaveConnectionData.Checked)
                {
                    connectionData.ConfigurationList.Add(new ConnectionConfiguration()
                    {
                        name = string.Format("{0}/{1} - {2}", serverUri, org, user.Text),
                        office365 = ckb_office365.Checked,
                        localuser = login.Checked,
                        serverUri = serverUri,
                        organization = org,
                        Password = ckbSavePassword.Checked ? password.Text : string.Empty,
                        user = user.Text,
                        ssl = ssl
                    });
                    connectionData.storeConnectionData();
                }
                if (organization.SelectedItem != null)
                {
                    GlobalApplicationData.Instance.connectionInProgress = true;
                    connection.OrganizationName = org;
                    ((ActionPanelEntityList)Globals.CrmAddIn.TaskPane.Control).showLoading(true);
                    ConnectAndLoad.RunWorkerAsync();
                    this.Close();
                }
                else
                {
                    DialogResult message = MessageBox.Show("Select an organization", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }


        private void ckb_crmonline_CheckedChanged(object sender, EventArgs e)
        {
            if (ckb_crmonline.Checked)
            {
                cmbonlineUrl.SelectedIndex = 0;
                cmbonlineUrl.Visible = true;
                port.Enabled = false;
                host.Visible = false;
                host.Text = cmbonlineUrl.Text;
                pnl_protocol.Enabled = false;
                protocol2.Checked = false;
                login.Checked = false;
                login.Enabled = false;
                ckb_office365.Visible = true;
            }
            else
            {
                cmbonlineUrl.Visible = false;
                host.Visible = true;
                port.Enabled = true;
                host.Text = string.Empty;
                pnl_protocol.Enabled = true;
                login.Enabled = true;
                ckb_office365.Checked = false;
                ckb_office365.Visible = false;
            }
        }

        private void cmbonlineUrl_SelectedIndexChanged(object sender, EventArgs e)
        {
            host.Text = cmbonlineUrl.Text;
        }


        private void ConnectAndLoad_DoWork(object sender, DoWorkEventArgs e) 
        {
            try
            {
                GlobalApplicationData.Instance.connectionInProgress = true;
                Globals.CrmAddIn.TaskPane.Visible = true;
                IServiceManagement<IOrganizationService> service = connection.ConnectToOrganization();
                OrganizationServiceProxy organizationProxy = connection.GetOrganizationProxy();
                Globals.CrmAddIn.crmOpHelper.Service = organizationProxy;
                GlobalOperations.LoadOperations();
            }
            catch (Exception ex)
            {
                exception = ex.Message;
                e.Cancel = true;
            }
        }

        private void ConnectAndLoad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                Globals.CrmAddIn.TaskPane.Visible = false;
                DialogResult message = MessageBox.Show(string.Format("Unable to Connect to {0} \n {1}", connection.ServerAddress.ToString(), exception), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (savedConnection)
                {
                    pnlMainPanel.Visible = true;
                    pnlOnlyPassword.Visible = false;
                    ptbLoadongBig.Visible = false;
                    cmbSavedConnections.SelectedIndex = 0;
                    savedConnection = false;
                }
                this.Show();
            }
            else
            {
                ((ActionPanelEntityList)Globals.CrmAddIn.TaskPane.Control).FillEntitiesList();
                parentribbon.enableRibbonButtons();
            }
            GlobalApplicationData.Instance.connectionInProgress = false;
        }

        private void CrmAuthenticationForm_Load(object sender, EventArgs e)
        {
            connectionData = new ConnectionsData();
            cmbSavedConnections.Items.Add(string.Empty);
            cmbSavedConnections.Items.AddRange(connectionData.ConfigurationList.Select(x => x.name).ToArray());
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            connectionData.ConfigurationList.Clear();
            connectionData.storeConnectionData();
            savedConnection = false;
            currentSavedConnection = null;
            cmbSavedConnections.Items.Clear();
        }

        private void cmbSavedConnections_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbSavedConnections.SelectedIndex <= 0)
            {
                pnlMainPanel.Visible = true;
                pnlOnlyPassword.Visible = false;
                ptbLoadongBig.Visible = false;
            }
            else
            {
                if (GlobalApplicationData.Instance.connectionInProgress)
                {
                    DialogResult message = MessageBox.Show("Another connection in progress", "Connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    currentSavedConnection = connectionData.ConfigurationList[cmbSavedConnections.SelectedIndex - 1];
                    savedConnection = true;
                    if (currentSavedConnection.Password != string.Empty)
                    {
                        if (currentSavedConnection.localuser)
                        {
                            connection = new CrmConnection(currentSavedConnection.ssl, currentSavedConnection.serverUri);
                        }
                        else
                        {
                            connection = new CrmConnection(currentSavedConnection.ssl, currentSavedConnection.serverUri, currentSavedConnection.user, currentSavedConnection.Password, currentSavedConnection.office365);
                        }
                        GlobalApplicationData.Instance.connectionInProgress = true;
                        retriveOrganization.RunWorkerAsync();
                        pnlMainPanel.Visible = false;
                        pnlOnlyPassword.Visible = false;
                        ptbLoadongBig.Visible = true;
                    }
                    else
                    {
                        pnlOnlyPassword.Visible = true;
                        ptbLoadongBig.Visible = false;
                        pnlMainPanel.Visible = false;
                    }
                }
            }
        }

        private void btnOnlyPassword_Click(object sender, EventArgs e)
        {

            if (GlobalApplicationData.Instance.connectionInProgress)
            {
                DialogResult message = MessageBox.Show("Another connection in progress", "Connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                if (currentSavedConnection != null && savedConnection)
                {
                    if (currentSavedConnection.localuser)
                    {
                        connection = new CrmConnection(currentSavedConnection.ssl, currentSavedConnection.serverUri);
                    }
                    else
                    {
                        connection = new CrmConnection(currentSavedConnection.ssl, currentSavedConnection.serverUri, currentSavedConnection.user, txtOnlyPassword.Text, currentSavedConnection.office365);
                    }
                    GlobalApplicationData.Instance.connectionInProgress = true;
                    ptbLoadongBig.Visible = true;
                    pnlMainPanel.Visible = false;
                    pnlOnlyPassword.Visible = false;
                    retriveOrganization.RunWorkerAsync();
                }
            }
        }

    }
}
